#include "movie.h"

#include <QImage>
#include <QBuffer>

Movie::Movie(int id, QObject *parent) :
    QObject(parent),
    tmdb_id_(0),
    id_(id),
    image_id_(0)
{
}

///
/// Generates a movie checksum from title or filename if exists
void Movie::createChecksum()
{
    QCryptographicHash hash(QCryptographicHash::Md5);
    QByteArray fileName;
    fileName.append(QFileInfo(getFilePath()).fileName());
    hash.addData(fileName, fileName.size());
    QByteArray result =  hash.result();
    checksum_ = result.toHex();
}

///
/// @return     The movie checksum
///
/// Returns the movie checksum
QString Movie::getChecksum()
{
    if (checksum_.length() == 0)
        createChecksum();
    return checksum_;
}

///
/// @param  cover   A byte array of the cover
/// @param  scale   True scals the image
///
/// Sets the cover of the movie. Can scale the cover if needed,
/// otherwise the cover will only be set.
void Movie::setCover(const QByteArray &cover, bool scale)
{
    if (scale) {
        QImage image = QImage::fromData(cover);
        QImage tImage;
        if (image.height() >= image.width())
            tImage = image.scaledToHeight(278);
        else
            tImage = image.scaledToWidth(185);

        QBuffer buffer(&cover_);
        buffer.open(QBuffer::ReadWrite);
        tImage.save(&buffer, "JPG");
    } else {
        cover_ = cover;
    }
}

///
/// @return     True if the save process successfully
///
/// Saves the movie to the database
bool Movie::saveToDatabase()
{
    bool state = false;
    bool coverImage = false;
    int imageId = 0;

    if (!cover_.isEmpty())
        coverImage = true;

    QSqlDatabase db = QSqlDatabase::database();

    if (getId().toInt() == 0) {
        // insert new movie
        db.transaction();
        QSqlQuery query;

        if (coverImage) {
            query.prepare("INSERT INTO images (image) VALUES (:image)");
            query.bindValue(":image", getCover().data());
            state = query.exec();

            if (!state)
                qDebug() << query.lastError().text();

            imageId = query.lastInsertId().toInt();
        }

        query.clear();
        query.prepare("INSERT INTO movies (IMAGE_ID, title, year, file_path, checksum, tmdb_id) "
                      "VALUES (:image_id, :title, :year, :file_path, :checksum, :tmdb_id)");
        query.bindValue(":image_id", imageId);
        query.bindValue(":title", getTitle());
        query.bindValue(":year", getYear());
        query.bindValue(":file_path", getFilePath());
        query.bindValue(":checksum", getChecksum());
        query.bindValue(":tmdb_id", getTmdbId());

        state = query.exec();
        id_ = query.lastInsertId().toInt();

        if (!state)
            qDebug() << query.lastError().text();

        if (!db.commit())
            db.rollback();
    } else if (getId().toInt() > 0) {
        // update existing movie
        db.transaction();
        QSqlQuery query;

        if (coverImage) {
            query.prepare("INSERT INTO images (image) VALUES (:image)");
            query.bindValue(":image", getCover());
            state = query.exec();

            if (!state)
                qDebug() << query.lastError().text();

            imageId = query.lastInsertId().toInt();
        }

        query.clear();
        query.prepare("UPDATE movies SET IMAGE_ID=:image_id, tmdb_id=:tmdb_id WHERE ID=:id");
        query.bindValue(":image_id", imageId);
        query.bindValue(":tmdb_id", getTmdbId());
        query.bindValue(":id", getId());

        state = query.exec();

        if (!state)
            qDebug() << query.lastError().text();

        if (!db.commit())
            db.rollback();
    }

    return state;
}

///
/// @param  lastInsertId    A pointer to the lastInsertId variable
///
/// @return     True if the saving process successfully complete
///
/// Saves the cover to the database
bool Movie::saveCover(int *lastInsertId)
{
    if (cover_.isEmpty())
        return false;

    QSqlDatabase db = QSqlDatabase::database();
    bool state = false;
    db.transaction();
    QSqlQuery query;

    query.prepare("INSERT INTO images (image) "
                  "VALUES (:image)");
    query.bindValue(":image", cover_);
    state = query.exec();

    if (!db.commit())
        db.rollback();

    if (state)
        *lastInsertId = query.lastInsertId().toInt();

    return state;
}

///
/// @return     True if the cover updated successfully
///
/// Update the cover in the database and the movie table
bool Movie::updateCover()
{
    if (cover_.isEmpty())
        return false;

    QSqlDatabase db = QSqlDatabase::database();
    bool state = false;

    db.transaction();
    QSqlQuery query;
    query.prepare("UPDATE images SET image=':image' WHERE ID=:id");
    query.bindValue(":image", cover_);
    query.bindValue(":id", image_id_);
    state = query.exec();
    if (!db.commit())
        db.rollback();

    return state;
}
